﻿using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using NodeBasedSkillEditor.ViewModel;

namespace NodeBasedSkillEditor.View
{
    public class DirectedAcyclicGraph : MultiSelector
    {
        public bool IsDrawingGrid {
            get { return (bool)GetValue(IsDrawingGridProperty); }
            set { SetValue(IsDrawingGridProperty, value); }
        }
        public static readonly DependencyProperty IsDrawingGridProperty =
            DependencyProperty.Register("IsDrawingGrid", typeof(bool), typeof(DirectedAcyclicGraph), 
                new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public float Zoom {
            get { return (float)GetValue(ZoomProperty); }
            set { SetValue(ZoomProperty, value); }
        }
        public static readonly DependencyProperty ZoomProperty =
            DependencyProperty.Register("Zoom", typeof(float), typeof(DirectedAcyclicGraph),
                new FrameworkPropertyMetadata(1f, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public Vector Pan {
            get { return (Vector)GetValue(PanProperty); }
            set { SetValue(PanProperty, value); }
        }
        public static readonly DependencyProperty PanProperty =
            DependencyProperty.Register("Pan", typeof(Vector), typeof(DirectedAcyclicGraph), 
                new FrameworkPropertyMetadata(new Vector(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public Point CurrMousePos {
            get { return (Point)GetValue(CurrMousePosProperty); }
            set { SetValue(CurrMousePosProperty, value); }
        }
        public static readonly DependencyProperty CurrMousePosProperty =
            DependencyProperty.Register("CurrMousePos", typeof(Point), typeof(DirectedAcyclicGraph), new PropertyMetadata(new Point()));

        public GridCanvas BackgroundCanvas { get; private set; }
        public NodeCanvas NodeCanvas { get; private set; }

        public VM_DAG ViewModel { get { return DataContext as VM_DAG; } }

        static DirectedAcyclicGraph()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DirectedAcyclicGraph), new FrameworkPropertyMetadata(typeof(DirectedAcyclicGraph)));
        }

        public DirectedAcyclicGraph()
        {
            Background = new SolidColorBrush(DAGHelper.DAGBackgroundColor);
            DataContextChanged += OnDataContextChanged;
        }

        private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (ViewModel != null)
            {
                ViewModel.Initialize(this);
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            BackgroundCanvas = GetTemplateChild("__GridCanvas__") as GridCanvas;
            NodeCanvas = GetTemplateChild("__NodeCanvas__") as NodeCanvas;
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            ViewModel.HandleKeyDown(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);
            ViewModel.HandleKeyUp(e);
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            Focus();
            base.OnMouseLeftButtonDown(e);
            ViewModel.OnLMBDown(e);
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            Focus();
            base.OnMouseLeftButtonUp(e);
            ViewModel.OnLMBUp(e);
        }

        protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
        {
            Focus();
            base.OnMouseRightButtonDown(e);
            ViewModel.OnRMBDown(e);
        }

        protected override void OnMouseRightButtonUp(MouseButtonEventArgs e)
        {
            Focus();
            base.OnMouseRightButtonUp(e);
            ViewModel.OnRMBUp(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            ViewModel.OnMouseMove(e);
        }

        protected override void OnMouseWheel(MouseWheelEventArgs e)
        {
            Focus();
            base.OnMouseWheel(e);
            ViewModel.OnMouseWheel(e);
        }

        //protected override void OnDragOver(DragEventArgs e)
        //{
        //    base.OnDragOver(e);
        //    ViewModel.OnDragOver(e);
        //}

        protected override void OnDrop(DragEventArgs e)
        {
            Focus();
            base.OnDrop(e);
            ViewModel.OnDrop(e);
        }

        protected override void OnLostFocus(RoutedEventArgs e)
        {
            base.OnLostFocus(e);
        }

    }
}
